package com.cenluan.ext.jfinal;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import com.jfinal.plugin.activerecord.Page;

/**
 * 自定义的扩展controller，增加了一些便捷操作方法，使继承类代码更简
 * 
 * @author peak
 * 
 */
public class PkController extends com.jfinal.core.Controller {
	/**
	 * 获取页码，项目里约定好页码的请求参数为pn，如解析为整数时出错，或者结果小于1，返回默认值1
	 * 
	 * @return
	 */
	public int getPn() {
		String pn = getPara("pn");
		try {
			int p = Integer.parseInt(pn);
			if (p < 1) {
				p = 1;
			}
			return p;
		} catch (NumberFormatException e) {
			return 1;
		}
	}

	/**
	 * 设置分页链接html到request里，在视图里可以用${pageLink}得到
	 * 
	 * @page
	 */
	@SuppressWarnings("rawtypes")
	public void setPageLink(Page page) {
		HttpServletRequest req = getRequest();
		String url = req.getRequestURI();
		StringBuilder html = new StringBuilder();
		int pn = page.getPageNumber();// 当前页码
		int tp = page.getTotalPage();// 总页数
		// 如果一共只有一页，不用生成链接了
		if (tp <= 1) {
			setAttr("pageLink", "");
			return;
		}
		// 根据request参数生成url
		Map<String, String[]> parameterMap = req.getParameterMap();
		Set<String> keySet = parameterMap.keySet();
		Iterator<String> keyIter = keySet.iterator();
		StringBuilder params = new StringBuilder();
		// 把请求的参数拼接起来
		while (keyIter.hasNext()) {
			String key = keyIter.next();
			String[] values = parameterMap.get(key);
			// 如果是页码的参数，跳过
			if ("pn".equals(key)) {
				continue;
			}
			for (String value : values) {
				params.append(key + "=" + value + "&");
			}
		}
		if ("".equals(params.toString())) {
			url = url + "?pn=";
		} else {
			url = url + "?" + params + "pn=";
		}
		// 起始页与结束页
		int ps = pn - 3;
		if (ps < 1) {
			ps = 1;
		}
		int pe = ps + 4;
		// 计算开始页与结束页
		if (pe > tp) {
			pe = tp;
		}
		if (pe == tp) {
			ps = pe - 4;
		}
		if (ps < 1) {
			ps = 1;
		}
		// 拼接ul开始标签
		html.append("<ul class='pagination'>");
		// 首页
		if (ps > 1) {
			html.append("<li><a href='" + url + "1'>1</a></li>");
		}
		// 省略号
		if (ps > 2) {
			html.append("<li class='disabled'><a>...</a></li>");
		}
		// 生成从ps到pe的分页链接
		for (int i = ps; i <= pe; i++) {
			if (pn == i) {
				html.append("<li class='active'><a>" + i + "</a></li>");
			} else {
				html.append("<li><a href='" + url + i + "'>" + i + "</a></li>");
			}
		}
		// 省略号
		if (tp - pe > 1) {
			html.append("<li class='disabled'><a>...</a></li>");
		}
		// 最后一页
		if (pe < tp) {
			html.append("<li><a href='" + url + tp + "'>" + tp + "</a></li>");
		}
		// 拼接ul结束标签
		html.append("</ul>");

		setAttr("pageLink", html.toString());
	}

	/**
	 * 设置分页数据到request里，方便视图层操作
	 * 
	 * @param page
	 */
	@SuppressWarnings("rawtypes")
	public void setPage(Page page) {
		setAttr("page", page);
		setPageLink(page);
	}

	/**
	 * 获取客户端真实ip，适用于使用了代理的情况
	 * 
	 * @param req
	 * @return
	 */
	public String getClientIp() {
		HttpServletRequest req = getRequest();
		String ip = req.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = req.getHeader("proxy-client-ip");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = req.getRemoteAddr();
		}
		// 如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值
		// 取X-Forwarded-For中第一个非unknown的有效IP字符串
		// 如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130,
		// 192.168.1.100
		// 用户真实IP为： 192.168.1.110
		if (ip.indexOf(",") != -1) {
			for (String str : ip.split(",")) {
				if (!"unkown".equalsIgnoreCase(str)) {
					ip = str;
					break;
				}
			}
		}
		return ip;
	}

	/**
	 * 获取servername，适用于代理的情况，包含端口号
	 * 
	 * @param req
	 * @return
	 */
	public String getServerName() {
		HttpServletRequest req = getRequest();
		String serverName = req.getHeader("X-FORWARDED-HOST");
		if (serverName == null || serverName.length() < 1) {
			serverName = req.getServerName()
					+ (req.getServerPort() == 80 ? "" : (":" + req
							.getServerPort()));
		} else if (serverName.contains(",")) {
			serverName = serverName.substring(0, serverName.indexOf(","))
					.trim();
		}
		return serverName;
	}

	/**
	 * 获取访问url的前缀，从http://一直包含到contextPath
	 * 
	 * @param req
	 * @return
	 */
	public String getUrlPrefix() {
		HttpServletRequest req = getRequest();
		String url = req.getScheme() + "://";
		url += getServerName();
		url += req.getContextPath();
		return url;
	}
}
